package trade

/*
#cgo CPPFLAGS: -fPIC -I./
#cgo linux LDFLAGS: -fPIC -L${SRCDIR} -Wl,-rpath ${SRCDIR} -ltaptrade -lstdc++

#include "struct_cgo.h"

void* CreateITapTradeAPINotify();
void* CreateTradeAPI(struct TapAPIApplicationInfo *appInfo);
void FreeITapTradeAPI(void* api);
void* GetAPIVersion();
void* GetErrorDescribe(int errorCode);

// ********************** 调用函数 ******************
[[ range .Fn ]]int [[ .FuncName ]](void* api[[ range .Params ]],[[ CHeaderBaseType .Type .Name]] [[ .Name ]][[end]]);
[[ end ]]


// ********************** 响应函数 ******************
[[ range .On ]]void Set[[ .FuncName ]](void*, void*);
[[ end ]]

// Onxxx 为go 的 export所用
[[ range .On ]]void ex[[ .FuncName ]]([[ range $i,$v := .Params ]][[ if gt $i 0 ]], [[ end ]] [[ CHeaderBaseType .Type .Name ]] [[ .Name ]][[end]]);
[[ end ]]

#include <stdlib.h>
#include <stdint.h>
*/
import "C"

import (
	"fmt"
	"io"
	"strings"
	"unsafe"

	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
)

func GBK(chars *C.char) string {
	rd := transform.NewReader(strings.NewReader(C.GoString(chars)), simplifiedchinese.GBK.NewDecoder())
	bs, _ := io.ReadAll(rd)
	return string(bs)
}

var t *Trade
func NewTrade()*Trade{
	if t==nil {
		t = &Trade{}
	}
	return t
}

// Trade 交易接口
type Trade struct {
	api, spi unsafe.Pointer
	// 定义响应函数变量
	[[ range .On ]][[ .FuncName ]] func([[ range $i,$v := .Params ]][[ if gt $i 0 ]], [[ end ]] [[ DefineVar .Type .Name ]][[end]])
	[[ end ]]
}

func (t *Trade) CreateITapTradeAPINotify() {
	t.spi = C.CreateITapTradeAPINotify()
}
func (t *Trade) CreateITapTradeAPI(appInfo *TapAPIApplicationInfo) {
	t.api = C.CreateTradeAPI((*C.struct_TapAPIApplicationInfo)(unsafe.Pointer(appInfo)))
}
func (t *Trade)FreeITapTradeAPI(api unsafe.Pointer)  {
	C.FreeITapTradeAPI(api)
}
func (t *Trade)GetITapTradeAPIVersion() string {
	return C.GoString((*C.char)(C.GetAPIVersion()))
}
func (t *Trade) GetITapErrorDescribe(errorCode TAPIINT32) string {
	return GBK((*C.char)(C.GetErrorDescribe(C.int(errorCode))))
}

// 替代 SetAPINotify
func (t *Trade) SetSpi() { C.SetAPINotify(t.api, t.spi) }

// ********************** 调用函数 ******************
[[ range .Fn ]]
func (t *Trade) [[ .FuncName ]]([[ range $i,$v := .Params ]][[ if gt $i 0 ]], [[ end ]][[ C2Go .Type .Name]][[ end ]]) C.int {return C.[[ .FuncName ]](t.api[[ range .Params ]], [[ Go2C .Type .Name ]][[ end ]])}
[[ end ]]

// ********************** 响应函数 ******************
func (t *Trade)RegCallBack(){
	[[ range .On ]]C.Set[[ .FuncName ]](t.spi, C.ex[[ .FuncName ]])
	[[ end ]]
}

[[ range .On ]]
//export ex[[ .FuncName ]]
func ex[[ .FuncName ]]([[ range $i,$v := .Params ]][[ if gt $i 0 ]], [[ end ]] [[ CCB .Type .Name ]][[end]]){
	if t.[[ .FuncName ]] != nil {
		t.[[ .FuncName ]]([[ range $i,$v := .Params ]][[ if gt $i 0 ]], [[ end ]] [[ cgo .Type .Name ]][[end]])
	} else {
		fmt.Println("[[ .FuncName ]]")
	}
}
[[ end ]]